#include "gamelogic.h"
#include "qipan.h"
#include <QRandomGenerator>
#include <QDebug>

Gamelogic::Gamelogic(QObject *parent) : QObject(parent)
{

}

/* 判断输赢 */
bool Gamelogic::CheckIsCount(int row, int col, Role role,int num)
{
    /* 四个方向 */
    const int direction[4][2] =
    {
      /* 水平 */
        {1,0},
      /* 垂直 */
        {0,1},
      /* 左对角线 */
        {1,1},
      /* 右对角线 */
        {1,-1}
    };

    /* 四个方向 */
    for(int direc = 0;direc < 4;direc++)
    {
        /* 初始化计数器 */
        int cnt = 1;

        /* 向一个方向的正方向探测 */
        for(int idx = 1;idx < 5;idx++)
        {
            int newRow = row + direction[direc][0] * idx;
            int newCol = col + direction[direc][1] * idx;

            if((newRow >= 0 && newRow < m_boardSize) &&(newCol >= 0 && newCol < m_boardSize) && m_board[newRow][newCol] == role )
            {
                cnt++;
            }
            else
            {
                break;
            }
        }

        /* 向一个方向的反方向探测 */
        for(int idx = 1;idx < 5;idx++)
        {
            int newRow = row - direction[direc][0] * idx;
            int newCol = col - direction[direc][1] * idx;

            if((newRow >= 0 && newRow < m_boardSize )&& (newCol >= 0&& newCol < m_boardSize) && (m_board[newRow][newCol] == role))
            {
                cnt++;
            }
            else
            {
                break;
            }
        }


        if(cnt >= num)
        {
            return  true;
        }


    }

    return false;

}

void Gamelogic::setQipanBoard(Role **board, int boardSize)
{
    m_board = board;
    m_boardSize = boardSize;
}

bool Gamelogic::Prevent(int num)
{
    //int num = 6;
    while(num-- > 2)
    {
        for(int i = 0;i < m_boardSize;i++)
        {
            for(int j = 0;j < m_boardSize;j++)
            {
                if(m_board[i][j] == EMPTY)
                {
                    m_board[i][j] = PLAYER;
                    if(CheckIsCount(i,j,PLAYER,num))
                    {
                        m_board[i][j] = COMPUTER;
                        return true;
                    }
                    m_board[i][j] = EMPTY;
                }
            }
        }
    }
    return false;

}

bool Gamelogic::Attack(int num)
{

//    int num = 5;
    while(num-- > 2)
    {
        for(int i = 0;i < m_boardSize;i++)
        {
            for(int j = 0;j < m_boardSize;j++)
            {
                if(m_board[i][j] == EMPTY)
                {
                    m_board[i][j] = COMPUTER;
                    if(CheckIsCount(i,j,COMPUTER,num))
                    {
                        return true;
                    }
                    m_board[i][j] = EMPTY;
                }
            }
        }
    }
    return false;
}

bool Gamelogic::AIMakeMove()
{

    //智能决策  策略
    //优先取胜策略
    for(int i = 0;i < m_boardSize;i++)
    {
        for(int j = 0;j < m_boardSize;j++)
        {
            if(m_board[i][j] == EMPTY)
            {
                m_board[i][j] = COMPUTER;
                if(CheckIsCount(i,j,COMPUTER,5))
                {
                    return true;
                }
               m_board[i][j] = EMPTY;
            }
        }
    }
//    //阻止对手策略
//    if(Attack())
//        return false;
//    if(Prevent())
//        return false;

for(int i = 5 ;i > 1;i--)
{
        if(Attack(i + 1))
            return false;
        if(Prevent(i))
            return false;
}


}


void Gamelogic::computerMove()
{
    int bestScore = 0;
    int bestRow = 0;
    int bestCol = 0;
    for(int row = 0;row < m_boardSize;row++)
    {
        for(int col = 0;col < m_boardSize;col++)
        {
            if(m_board[row][col] == 0)
            {
                /* 判断这个点对AI来说最有利 */
                /* 1.I 对你自己最好的点 + 2.对对手最不好的点() */
                int score = evaluateMove(row,col,COMPUTER) + evaluateMove(row,col,PLAYER);
                if(bestScore < score)
                {
                    bestScore = score;
                    bestRow = row;
                    bestCol = col;
                }
            }
        }
    }

    emit Aiposition(bestRow,bestCol);
}

int Gamelogic::evaluateMove(int row, int col, Role role)
{
    /* 连子数 + 开放端 */

    /* 四个方向 */
    const int directions[4][2] =
    {
      /* 水平 */
        {1,0},
      /* 垂直 */
        {0,1},
      /* 左对角线 */
        {1,1},
      /* 右对角线 */
        {1,-1}
    };
    int score = 0;
    /* 四个方向 */
    for(int direct = 0;direct < 4;direct++)
    {
        /* 连子数 */
        int count = 0;
        /* 开放端 */
        int openEnds = 0;
        /* 向同一个方向探测最多四个棋子 */
        for(int idx = 1;idx <= 4;idx++)
        {
            int newRow = row + directions[direct][0] * idx;
            int newCol = col + directions[direct][1] * idx;

            if((newRow >= 0 && newRow < m_boardSize) &&(newCol >= 0 && newCol < m_boardSize) )
            {
                if(m_board[newRow][newCol] == role)
                {
                    count++;
                }
                else if(m_board[newRow][newCol] == EMPTY)
                {
                    openEnds++;
                    break;
                }
                else
                {
                    /* 遇到对手 */
                    break;
                }
            }
            else
            {
                break;
            }
        }

        /* 向同一个反方向探测最多四个棋子 */
        for(int idx = 1;idx <= 4;idx++)
        {
            int newRow = row - directions[direct][0] * idx;
            int newCol = col - directions[direct][1] * idx;

            if((newRow >= 0 && newRow < m_boardSize) &&(newCol >= 0 && newCol < m_boardSize) )
            {
                if(m_board[newRow][newCol] == role)
                {
                    count++;
                }
                else if(m_board[newRow][newCol] == EMPTY)
                {
                    openEnds++;
                    break;
                }
                else
                {
                    /* 遇到对手 */
                    break;
                }
            }
            else
            {
                break;
            }
        }

        if(count == 4 && openEnds > 0)
        {
            score += 10000;
        }
        else if(count == 3 && openEnds > 0)
        {
            score += 1000;
        }
        else if(count == 2 && openEnds > 0)
        {
            score += 100;
        }
        else if(count == 1 && openEnds > 0)
        {
            score += 10;
        }
    }

    return score;
}



